From 2c6f432e14345aacd41430870a7fc7fc68f8f8a2 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 17 Apr 2003 12:26:14 +0000 Subject: [PATCH] bitkeeper revision 1.179 (3e9e9d6686NgD7eyGZqkrhBZ7IgkDw) sched.h, schedule.c, domain.c, dom0_ops.c, dom_builder.c: Fixed domain death so we can now kill domains that were never actually launched. --- tools/domain_builder/dom_builder.c | 46 ++++++++++++++++++++++++------ xen/common/dom0_ops.c | 18 +++++++----- xen/common/domain.c | 42 ++++++++++++++++++--------- xen/common/schedule.c | 2 +- xen/include/xeno/sched.h | 5 ++-- 5 files changed, 81 insertions(+), 32 deletions(-) diff --git a/tools/domain_builder/dom_builder.c b/tools/domain_builder/dom_builder.c index d2ba7db2c7..13ee8d8735 100644 --- a/tools/domain_builder/dom_builder.c +++ b/tools/domain_builder/dom_builder.c @@ -43,6 +43,30 @@ static void dbstatus(char * msg) printf("Domain Builder: %s\n", msg); } +static int do_kill_domain(int dom_id, int force) +{ + char cmd_path[MAX_PATH]; + dom0_op_t dop; + int cmd_fd; + + dop.cmd = DOM0_KILLDOMAIN; + dop.u.killdomain.domain = dom_id; + dop.u.killdomain.force = force; + + /* open the /proc command interface */ + sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD); + cmd_fd = open(cmd_path, O_WRONLY); + if(cmd_fd < 0){ + perror(PERR_STRING); + return -1; + } + + write(cmd_fd, &dop, sizeof(dom0_op_t)); + close(cmd_fd); + + return 0; +} + /* clean up domain's memory allocations */ static void dom_mem_cleanup(dom_mem_t * dom_mem) { @@ -162,7 +186,7 @@ static dom0_newdomain_t * create_new_domain(long req_mem) sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_DOM_DATA); - while((id_fd = open(dom_id_path, O_RDONLY)) < 0){} + while((id_fd = open(dom_id_path, O_RDONLY)) < 0) continue; dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t)); read(id_fd, dom_data, sizeof(dom0_newdomain_t)); close(id_fd); @@ -445,20 +469,18 @@ int main(int argc, char **argv) if(argc < 4) { dberr("Usage: dom_builder " "[] \n"); - goto out; + return -1; } /* create new domain and set up all the neccessary mappings */ kernel_fd = do_kernel_chcks(argv[2], atol(argv[1]), &load_addr, &ksize); - if(kernel_fd < 0) { - rc = errno; - goto out; - } + if(kernel_fd < 0) + return -1; /* request the creation of new domain */ if(!(dom_data = create_new_domain(atol(argv[1])))) - goto out; + return -1; /* map domain's memory */ if(map_dom_mem(dom_data->pg_head, dom_data->memory_kb >> (PAGE_SHIFT-10), @@ -520,7 +542,13 @@ int main(int argc, char **argv) out: if( rc >= 0 ) - return meminfo->domain; + { + return meminfo->domain; + } else - return rc; + { + if ( dom_data->domain != 0 ) + do_kill_domain(dom_data->domain, 1); + return rc; + } } diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 6344254a3e..d803c8e5ca 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -65,11 +65,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) { struct task_struct * p = find_domain_by_id(op.u.meminfo.domain); if ( (ret = final_setup_guestos(p, &op.u.meminfo)) != 0 ) - { - p->state = TASK_DYING; - release_task(p); break; - } wake_up(p); reschedule(p); ret = p->domain; @@ -83,13 +79,21 @@ long do_dom0_op(dom0_op_t *u_dom0_op) static unsigned int pro = 0; unsigned int dom = get_domnr(); ret = -ENOMEM; - if ( dom == 0 ) break; + + if ( dom == 0 ) + break; + pro = (pro+1) % smp_num_cpus; p = do_newdomain(dom, pro); - if ( p == NULL ) break; + if ( p == NULL ) + break; ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb); - if ( ret != 0 ) break; + if ( ret != 0 ) + { + __kill_domain(p); + break; + } build_page_list(p); diff --git a/xen/common/domain.c b/xen/common/domain.c index ab311f804e..14fcf8eaec 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -37,7 +37,7 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu) retval = -ENOMEM; p = alloc_task_struct(); - if (!p) goto newdomain_out; + if ( p == NULL ) return NULL; memset(p, 0, sizeof(*p)); atomic_set(&p->refcnt, 1); @@ -75,10 +75,10 @@ struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu) SET_LINKS(p); write_unlock_irqrestore(&tasklist_lock, flags); - newdomain_out: return(p); } + /* Get a pointer to the specified domain. Consider replacing this * with a hash lookup later. * @@ -110,33 +110,45 @@ void kill_domain_with_errmsg(const char *err) } -/* Kill the currently executing domain. */ -void kill_domain(void) +void __kill_domain(struct task_struct *p) { struct list_head *ent; net_vif_t *vif; - if ( current->domain == 0 ) + if ( p->domain == 0 ) { extern void machine_restart(char *); printk("Domain 0 killed: rebooting machine!\n"); machine_restart(0); } - printk("Killing domain %d\n", current->domain); + printk("Killing domain %d\n", p->domain); - sched_rem_domain(current); + sched_rem_domain(p); - unlink_blkdev_info(current); + unlink_blkdev_info(p); - while ( (ent = current->net_vifs.next) != ¤t->net_vifs ) + while ( (ent = p->net_vifs.next) != &p->net_vifs ) { vif = list_entry(ent, net_vif_t, dom_list); unlink_net_vif(vif); } - - schedule(); - BUG(); /* never get here */ + + if ( p == current ) + { + schedule(); + BUG(); /* never get here */ + } + else + { + free_task_struct(p); + } +} + + +void kill_domain(void) +{ + __kill_domain(current); } @@ -148,7 +160,11 @@ long kill_other_domain(unsigned int dom, int force) p = find_domain_by_id(dom); if ( p == NULL ) return -ESRCH; - if ( force ) + if ( p->state == TASK_SUSPENDED ) + { + __kill_domain(p); + } + else if ( force ) { cpu_mask = mark_hyp_event(p, _HYP_EVENT_DIE); hyp_event_notify(cpu_mask); diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 117af485c6..303dba32ba 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -107,7 +107,7 @@ static inline int __task_on_runqueue(struct task_struct *p) ******************************************************************************/ void sched_add_domain(struct task_struct *p) { - p->state = TASK_UNINTERRUPTIBLE; + p->state = TASK_SUSPENDED; p->mcu_advance = 10; if (p->domain == IDLE_DOMAIN_ID) { diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h index df63cfafac..5534ee45f3 100644 --- a/xen/include/xeno/sched.h +++ b/xen/include/xeno/sched.h @@ -163,7 +163,7 @@ struct task_struct { * TASK_UNINTERRUPTIBLE: Domain is blocked but may not be woken up by an * arbitrary event or timer. * TASK_WAIT: Domains CPU allocation expired. - * TASK_STOPPED: not really used in Xen + * TASK_SUSPENDED: Domain is in supsended state (eg. start of day) * TASK_DYING: Domain is about to cross over to the land of the dead. */ @@ -171,8 +171,8 @@ struct task_struct { #define TASK_INTERRUPTIBLE 1 #define TASK_UNINTERRUPTIBLE 2 #define TASK_WAIT 4 +#define TASK_SUSPENDED 8 #define TASK_DYING 16 -/* #define TASK_STOPPED 8 not really used */ #define SCHED_YIELD 0x10 @@ -219,6 +219,7 @@ extern int final_setup_guestos(struct task_struct *p, dom_meminfo_t *); struct task_struct *find_domain_by_id(unsigned int dom); extern void release_task(struct task_struct *); +extern void __kill_domain(struct task_struct *p); extern void kill_domain(void); extern void kill_domain_with_errmsg(const char *err); extern long kill_other_domain(unsigned int dom, int force); -- 2.30.2